using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Audio;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.GamerServices;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Media;
using TiledLib;
using System.IO;
using JMBucknall.Containers;
using System.Collections;


namespace WindowsGame4
{
    /// <summary>
    /// This is the main type for your game
    /// </summary>
    public class Game1 : Microsoft.Xna.Framework.Game
    {
        GraphicsDeviceManager graphics;
        public static SpriteBatch spriteBatch;
        Map map;
        Texture2D blank;
        ReadOnlyCollection<MapObject> objs;
        Texture2D textPlayer;
        Texture2D textCell;
        public static Texture2D textExplosion;
        public static Texture2D textVisionCell;
        World world;
        GameInfo gameInfo;
        int x;
        int y;
        float timeLastUpdate;
        Dictionary<String, Model> models;
        KeyboardState lastState;
        float timeLastKey;
        float timeLastDraw;
        AIInterface aiInterface;
        public static SpriteFont font;
        public static Texture2D textCellVision;
        public static Texture2D textColision;
        Texture2D textBackground;
        int sizeCell;
        String status;
        Texture2D textGameOver;
        float timeLastItem;
        float timeInitialCount;
        Boolean pause;
        String lastKey;
        Song bgMusic;
        public int numPlayers;
        public static SoundEffect projectileSound;
        public static SoundEffect explosionProjectileSound;
        public static SoundEffect timeBombSound;
        public static SoundEffect bombExplosion;
        public static SoundEffect selectedOption;
        public static Boolean enableMusic;
        public static Texture2D textEnergy;
        public static Texture2D textEnergyBorder;
        public static Texture2D textLife;
        public static Texture2D textLifeBorder;
        public static Texture2D textMiniStar;
        public static Texture2D textAmmoMenu;
        public static Texture2D textExplosionCross;
        public static Texture2D textExplosionSide;
        public static Texture2D textExplosionCloseSide;
        public static Boolean modeDebug;
        public static Texture2D textMenu;
        public static Texture2D textCurrectMenu;
        public static Texture2D textMenuSoloPlay;
        public static Texture2D textMenuBattlePlay;
        public static Texture2D textMenuHowToPlay;
        public static Texture2D textMenuCredits;
        public static Texture2D textMenuExit;
        public static Texture2D textMenuSelectMission;
        public static Texture2D textMenuSelectMissionBack;
        public static Texture2D textMenuSelectMission1;
        public static Texture2D textMenuSelectMission2;
        public static Texture2D textStadisticsRed;
        public static Texture2D textStadisticsGreen;
        public static Texture2D textPlayerWin;
        public static Texture2D textPlayer1Win;
        public static Texture2D textPlayer2Win;
        public static Texture2D textMenuSelectedMission;
        public static Texture2D textMenuDisableMission;
        public static Texture2D textMenuEnableMission;
        public static Texture2D textCurrentMission;
        public static Texture2D text3;
        public static Texture2D text2;
        public static Texture2D text1;
        public static Texture2D textGo;
        public static Texture2D textHowtoplay;
        public static Texture2D textHowtoplayBack;
        Boolean previousSelected;
        int initialCount;
        public Game1()
        {
            graphics = new GraphicsDeviceManager(this);
            Content.RootDirectory = "Content";
            //this.graphics.IsFullScreen = true;
            this.graphics.PreferredBackBufferWidth = 1024;
            this.graphics.PreferredBackBufferHeight = 768;
            timeLastUpdate = 0;
            timeLastItem = 0;
            timeLastKey = 0;
            status = "menu";
            
            pause = false;
            lastKey = "";
            timeLastDraw = 0;
            enableMusic = true;
            modeDebug = false;
            previousSelected = true;
            numPlayers = 1;
            initialCount = 3;
            timeInitialCount = 0;
        }

        /// <summary>
        /// Allows the game to perform any initialization it needs to before starting to run.
        /// This is where it can query for any required services and load any non-graphic
        /// related content.  Calling base.Initialize will enumerate through any components
        /// and initialize them as well.
        /// </summary>
        protected override void Initialize()
        {
            // TODO: Add your initialization logic here
            IsMouseVisible = true;
            base.Initialize();
            
        }

        public void updateMinMission(int level)
        {
            StreamWriter streamWritter = new StreamWriter("Content\\mission.txt");
            streamWritter.Write(level);
            streamWritter.Close();
        }

        public void loadMission(int level)
        {
            loadLevel(level);

        }

        public void loadModels()
        {
            models = new Dictionary<string, Model>();

            StreamReader streamReader = new StreamReader("Content\\models.txt");

            String line = streamReader.ReadLine();
            while (line != null)
            {
                String[] strModel = line.Split(';');
                String idModel = strModel[0].Trim();

                Model model = new Model(idModel);
                // Load animations
                String[] strAnimations = strModel[1].Split(',');
                for (int i = 0; i < strAnimations.Length; i++)
                {
                    String idAnimation = strAnimations[i].Trim();
                    System.Console.WriteLine(idAnimation);
                    Animation animation = new Animation(idAnimation, true);
                    Boolean error = false;
                    int count = 0;
                    while (error == false)
                    {
                        try
                        {
                           
                            Texture2D texture = Content.Load<Texture2D>(idModel + "_" + idAnimation + "_" + count);
                            Frame frame = new Frame(new Texture(texture, texture.Width, texture.Height));
                            animation.addFrame(frame);
                            
                            System.Console.WriteLine("Loading: " + idModel + "_" + idAnimation + "_" + count);
                            count++;
                            //System.Console.WriteLine(idAnimation + "_" + i);
                        }
                        catch (Exception ex)
                        {
                            error = true;
                        }
                    }
                    model.addAnimation(idAnimation, animation);
                }
                models.Add(idModel, model);
                System.Console.WriteLine("Model: " + idModel);
                line = streamReader.ReadLine();
                
            }
            //Console.ReadKey();
        }

        /// <summary>
        /// LoadContent will be called once per game and is the place to load
        /// all of your content.
        /// </summary>
        protected override void LoadContent()
        {
            aiInterface = AIInterface.getInstance();
            // Create a new SpriteBatch, which can be used to draw textures.
            spriteBatch = new SpriteBatch(GraphicsDevice);
            loadModels();
            font = Content.Load<SpriteFont>("SpriteFont1");
            
            blank = new Texture2D(GraphicsDevice, 1, 1);
            blank.SetData(new[] { Color.White });
            textPlayer = Content.Load<Texture2D>("player_front_0");
            textCell = Content.Load<Texture2D>("cell");
            textVisionCell = Content.Load<Texture2D>("visionCell");
            textExplosion = Content.Load<Texture2D>("bomb_explosion_0");
            textCellVision = Content.Load<Texture2D>("visionCell");
            textGameOver = Content.Load<Texture2D>("gameOver");
            textBackground = Content.Load<Texture2D>("background");
            textColision = Content.Load<Texture2D>("colision");
            bgMusic = Content.Load<Song>("bgMusic");
            projectileSound = Content.Load<SoundEffect>("projectileSound");
            explosionProjectileSound = Content.Load<SoundEffect>("explosionProjectileSound");
            timeBombSound = Content.Load<SoundEffect>("timeBomb");
            bombExplosion = Content.Load<SoundEffect>("bombExplosion");
            textEnergy = Content.Load<Texture2D>("energy");
            textEnergyBorder = Content.Load<Texture2D>("energyBorder");
            textLife = Content.Load<Texture2D>("life");
            textLifeBorder = Content.Load<Texture2D>("lifeBorder");
            textMiniStar = Content.Load<Texture2D>("miniStar");
            textAmmoMenu = Content.Load<Texture2D>("ammoMenu");
            textMenu = Content.Load<Texture2D>("menu");
            textCurrectMenu = textMenu;
            textMenuSoloPlay = Content.Load<Texture2D>("menuSoloPlay");
            textMenuBattlePlay = Content.Load<Texture2D>("menuBattlePlay");
            textMenuHowToPlay = Content.Load<Texture2D>("menuHowToPlay");
            textMenuCredits = Content.Load<Texture2D>("menuCredits");
            textMenuExit = Content.Load<Texture2D>("menuExit");
            selectedOption = Content.Load<SoundEffect>("selected");
            textMenuSelectMission = Content.Load<Texture2D>("menuSelectMission");
            textMenuSelectMissionBack = Content.Load<Texture2D>("menuSelectMissionBack");
            textMenuSelectMission1 = Content.Load<Texture2D>("menuSelectMission1");
            textMenuSelectMission2 = Content.Load<Texture2D>("menuSelectMission2");
            textStadisticsRed = Content.Load<Texture2D>("stadisticsRed");

            textStadisticsGreen = Content.Load<Texture2D>("stadisticsGreen");
            textPlayerWin = Content.Load<Texture2D>("playerWin");
            textPlayer1Win = Content.Load<Texture2D>("player1Win");
            textPlayer2Win = Content.Load<Texture2D>("player2Win");
            

            textMenuSelectedMission = Content.Load<Texture2D>("selectedMission");
            textMenuDisableMission = Content.Load<Texture2D>("disableMission");
            textMenuEnableMission = Content.Load<Texture2D>("enableMission");
            text3 = Content.Load<Texture2D>("3");
            text2 = Content.Load<Texture2D>("2");
            text1 = Content.Load<Texture2D>("1");
            textGo = Content.Load<Texture2D>("go");
            textHowtoplay = Content.Load<Texture2D>("howtoplay");
            textHowtoplayBack = Content.Load<Texture2D>("howtoplayBack");
            /*
            textExplosionCross = Content.Load<Texture2D>("cross");
            textExplosionSide  = Content.Load<Texture2D>("side");
            textExplosionCloseSide = Content.Load<Texture2D>("closeSide");
            */

            //use this to repeat the music
            MediaPlayer.IsRepeating = true;
            //play the music
            if(enableMusic)
                MediaPlayer.Play(bgMusic);
            //MediaPlayer.Stop();
            
            // TODO: use this.Content to load your game content here
            // Initialize gameInfo
            gameInfo = GameInfo.getInstance();

            gameInfo.models = models;

            // Load actual mission
            /*
            StreamReader streamReader = new StreamReader("Content\\mission.txt");

            String line = streamReader.ReadLine().Trim();
            System.Console.WriteLine("line: " + line);
            */

            /*
            StreamWriter streamWritter = new StreamWriter("Content\\mission.txt");
            streamWritter.Write("2");
            streamWritter.Close();
            */

            StreamReader streamReader = new StreamReader("Content\\mission.txt");
            String line = streamReader.ReadLine().Trim();
            gameInfo.MinMission = int.Parse(line);
            streamReader.Close();


            gameInfo.Level = 1;
            loadMission(gameInfo.Level);
        }

        public void loadLevel(int num)
        {
            map = Content.Load<Map>("mission"+num);
            //map = Content.Load<Map>("Map");
            world = new World(map.Height, map.Width, map.TileWidth);
            gameInfo.World = world;
            // Restar gameInfo
            gameInfo.reset();
            // Load map
            loadMap();
        }

        public void loadMap()
        {
            sizeCell = map.TileWidth;

            MapObjectLayer objects = map.GetLayer("Objects") as MapObjectLayer;
          
            objs = objects.Objects;

            // Set objects on the world
            for (int count = 0; count < objs.Count; count++)
            {
                MapObject obj = objs[count];
                if (obj.Type == "player")
                {
                    System.Console.WriteLine(obj.Bounds.X + " " + obj.Bounds.Y + " " + obj.Bounds.Left + " " + obj.Bounds.Bottom);

                    String team = (String)obj.Properties["team"];
                    String model = "enemy";
                    if (team == "green")
                        model = "player";

                    Object o = gameInfo.registerPlayer(new Position2D(obj.Bounds.X, obj.Bounds.Y), models[model]);
                    //System.Console.ReadKey();
                    loadDirection(o, (String)obj.Properties["direction"]);
                    int row = world.getNumRow(o.Position.Y);
                    int column = world.getNumColumn(o.Position.X);
                    //Cell cell = world.get(row, column);
                    //cell.Obj = o;
                    o.Name = (String)obj.Properties["name"];
                    o.Team = (String)obj.Properties["team"];
                    o.Lives = (int)obj.Properties["lives"];
                    o.Level = (int)obj.Properties["level"];
                    o.GunAmmo = (int)obj.Properties["gunAmmo"];
                    o.BombAmmo = (int)obj.Properties["bombAmmo"];
                    o.InitialLives = (int)obj.Properties["lives"];
                    o.InitalLevel = o.Level;

                    switch (o.Direction.getDirection())
                    {
                        case "left":
                            {
                                o.changeAnimation("left");
                                break;
                            }
                        case "right":
                            {
                                o.changeAnimation("right");
                                break;
                            }
                        case "up":
                            {
                                o.changeAnimation("back");
                                break;
                            }
                        case "down":
                            {
                                o.changeAnimation("front");
                                break;
                            }
                    }
                    //String col = ((String)obj.Properties["colision"]);
                    //Rectangle rect = new Rectangle(int.Parse(col.Split('_')[0]), int.Parse(col.Split('_')[1]), int.Parse(col.Split('_')[2]), int.Parse(col.Split('_')[3]));
                    //o.Colision = rect;

                    aiInterface.registerObject(o.Id, AIObject.TypeAIObject.AIPlayer);
                }
                if (obj.Type == "wall")
                {
                    int posX = obj.Bounds.X;
                    int posY = obj.Bounds.Y;
                    Position2D position = new Position2D(posX, posY);
                    String imageName = ((String)obj.Properties["image"]);
                    int depth = 0;
                    try
                    {
                        depth = (int)obj.Properties["depth"];
                    }
                    catch (Exception)
                    {

                    }
                    Model model = models[imageName];

                    Wall wall = gameInfo.registerWall(position, model);
                    wall.Depth = depth;
                    int numColisionsY = obj.Bounds.Height / sizeCell;
                    wall.Height = obj.Bounds.Height;
                    /*
                    // Calculate number of colisions in the axis X
                    int numColisionsX = obj.Bounds.Width / sizeCell;
                    // Calculate number of colisions in the axis Y
                    int numColisionsY = obj.Bounds.Height / sizeCell;

                    int posX = obj.Bounds.X;
                    int posY = obj.Bounds.Y;
                    for (int i = 0; i < numColisionsY; i++)
                    {
                        for (int j = 0; j < numColisionsX; j++)
                        {
                            Position2D position = new Position2D(posX, posY);

                            String imageName = ((String)obj.Properties["image"]);
                            int depth = 0;
                            try
                            {
                                depth = (int)obj.Properties["depth"];
                            }
                            catch (Exception)
                            {

                            }
                            Model model = models[imageName];
                                
                            Wall wall = gameInfo.registerWall(position, model);
                            wall.Depth = depth;
                            // ADD colision world
                            int row = world.getNumRow(position.Y);
                            int column = world.getNumColumn(position.X);
                            Cell cell = world.get(row, column);

                            posX += sizeCell;
                        }
                        posY += sizeCell;
                        posX = obj.Bounds.X;
                    }
                    */
                }

                if (obj.Type == "colision")
                {
                    
                    Boolean divide = (Boolean)obj.Properties["divide"];
                    int life = (int)obj.Properties["life"];
                    if (divide == true)
                    {
                        // Calculate number of colisions in the axis X
                        int numColisionsX = obj.Bounds.Width / sizeCell;
                        // Calculate number of colisions in the axis Y
                        int numColisionsY = obj.Bounds.Height / sizeCell;

                        int posX = obj.Bounds.X;
                        int posY = obj.Bounds.Y;
                        for (int i = 0; i < numColisionsY; i++)
                        {
                            for (int j = 0; j < numColisionsX; j++)
                            {
                                Position2D position = new Position2D(posX, posY);
                                Boolean destroyable = false;
                                if (life > 0)
                                    destroyable = true;


                                String col = ((String)obj.Properties["colision"]);
                                Model model = null;
                                Rectangle rect = new Rectangle(int.Parse(col.Split('_')[0]), int.Parse(col.Split('_')[1]), int.Parse(col.Split('_')[2]), int.Parse(col.Split('_')[3]));

                                Colision colision = gameInfo.registerColision(position, model, destroyable, life);
                                colision.Colision = rect;
                                colision.TypeColision = ((String)obj.Properties["type"]);
                                // ADD colision world
                                if (colision.TypeColision == "character")
                                {
                                    int row = world.getNumRow(position.Y);
                                    int column = world.getNumColumn(position.X);
                                    Cell cell = world.get(row, column);
                                    cell.Obj = colision;
                                }
                                posX += sizeCell;
                            }
                            posY += sizeCell;
                            posX = obj.Bounds.X;
                        }
                        //System.Console.Read();
                    }
                    //System.Console.WriteLine(world);
                    //System.Console.Read();
                    //System.Console.Read();
                }
                if (obj.Type == "enemy")
                {
                    String team = (String)obj.Properties["team"];
                    String model = "enemy";
                    if (team == "green")
                        model = "player";
                    Object o = gameInfo.registerEnemy(new Position2D(obj.Bounds.X, obj.Bounds.Y), models[model]);
                    loadDirection(o, (String)obj.Properties["direction"]);
                    aiInterface.registerObject(o.Id, AIObject.TypeAIObject.AIEnemy);
                    int row = world.getNumRow(o.Position.Y);
                    int column = world.getNumColumn(o.Position.X);
                    //Cell cell = world.get(row, column);
                    //cell.Obj = o;
                    o.Lives = (int)obj.Properties["lives"];
                    o.InitialLives = (int)obj.Properties["lives"];
                    o.Level =(int)obj.Properties["level"];
                    o.Name = (String)obj.Properties["name"];
                    o.GunAmmo = (int)obj.Properties["gunAmmo"];
                    o.BombAmmo = (int)obj.Properties["bombAmmo"];
                    try
                    {
                        o.FireFriendly = (Boolean)obj.Properties["fireFriendly"];
                    }
                    catch (Exception)
                    {

                    }
                    o.Team = team;
                    o.InitalLevel = o.Level;
                }
                if (obj.Type == "gunAmmo")
                {
                    Object o = gameInfo.registerItem(new Position2D(obj.Bounds.X, obj.Bounds.Y), models["gunAmmo"]);
                    o.GunAmmo += 10;
                }
                if (obj.Type == "bombAmmo")
                {
                    Object o = gameInfo.registerItem(new Position2D(obj.Bounds.X, obj.Bounds.Y), models["bombAmmo"]);
                    o.BombAmmo += 10;
                }
                if (obj.Type == "level")
                {
                    Object o = gameInfo.registerItem(new Position2D(obj.Bounds.X, obj.Bounds.Y), models["level"]);
                    o.Level += 1;
                }
            }
            System.Console.WriteLine(gameInfo.World);
           // Console.ReadKey();
        }

        void loadDirection(Object obj, String direction)
        {
            switch (direction)
            {
                case "left":
                    {
                        obj.Direction = new Direction2D(-1, 0);
                        break;
                    }
                case "right":
                    {
                        obj.Direction = new Direction2D(1, 0);
                        break;
                    }

                case "up":
                    {
                        obj.Direction = new Direction2D(0, -1);
                        break;
                    }
                case "down":
                    {
                        obj.Direction = new Direction2D(0, 1);
                        break;
                    }
            }
        }
        /// <summary>
        /// UnloadContent will be called once per game and is the place to unload
        /// all content.
        /// </summary>
        protected override void UnloadContent()
        {
            // TODO: Unload any non ContentManager content here
        }

        public void checkMouseMenu()
        {
            MouseState mouseState = Mouse.GetState();
            if (mouseState.LeftButton == ButtonState.Pressed)
            {
                System.Console.WriteLine(mouseState.X + "," + mouseState.Y);
                int posX = mouseState.X;
                int posY = mouseState.Y;
                if (posX > 253 && posX < 786 && posY > 338 && posY < 413)
                {
                    // start game
                    
                    status = "popupLevel";
                }
                else
                {
                    if (posX > 414 && posX < 628 && posY > 609 && posY < 675)
                    {
                        Exit();
                    }
                }
            }
        }

        public Boolean checkPlayerWin()
        {
            ArrayList characters = gameInfo.getCharacters();
            if (characters.Count == 1)
            {
                Object obj = (Object)characters[0];
                if (obj.Team == "green")
                {
                    status = "win";
                    textCurrectMenu = textPlayerWin;
                    return true;
                }
                else
                {
                    status = "gameOver";
                    textCurrectMenu = textGameOver;
                }
            }
            else
            {
                Boolean live = false;
                for (int i = 0; i < characters.Count; i++)
                {
                    Object obj = (Object)characters[i];
                    if (obj.Type == Object.TypeObject.player)
                        live = true;
                }
                if (live == false)
                {
                    status = "gameOver";
                    textCurrectMenu = textGameOver;
                }
            }
            return false;
        }

        public Boolean checkStarWin(int number)
        {
            ArrayList characters = gameInfo.getCharacters();
            for (int i = 0; i < characters.Count; i++)
            {
                Object obj = (Object)characters[i];
                if (obj.Level == number)
                {
                    if (obj.Team == "green")
                    {
                        status = "win";
                        textCurrectMenu = textPlayerWin;
                        return true;
                    }
                    else
                    {
                        status = "gameOver";
                        textCurrectMenu = textGameOver;
                    }
                }
            }
            return false;
        }
        public Boolean checkTeamWin()
        {
            // Team green wins
            ArrayList characters = gameInfo.getCharacters();

            int numGreen = 0;
            int numRed = 0;

            for (int i = 0; i < characters.Count; i++)
            {
                Object obj = (Object)characters[i];
                if (obj.Team == "red")
                    numRed++;
                else
                    numGreen++;
            }

            if (numGreen > 0 && numRed == 0)
            {
                status = "win";
                textCurrectMenu = textPlayerWin;
                return true;
            }
            else
            {
                if (numRed > 0 && numGreen == 0)
                {
                    status = "gameOver";
                    textCurrectMenu = textGameOver;
                }
            }
            return false;
        }

        public Boolean checkKillsWin(int number)
        {
            ArrayList characters = gameInfo.getCharacters();
            for (int i = 0; i < characters.Count; i++)
            {
                Object obj = (Object)characters[i];
                if (obj.Kills == number)
                {
                    if (obj.Team == "green")
                    {
                        status = "win";
                        textCurrectMenu = textPlayerWin;
                        return true;
                    }
                    else
                    {
                        status = "gameOver";
                        textCurrectMenu = textGameOver;
                    }
                }
            }
            return false;
        }
        public void checkFinish()
        {
            switch (gameInfo.Level)
            {
                case 1:
                    {
                        // Player kill all enemies
                        if (checkPlayerWin())
                        {
                            if (gameInfo.MinMission == 1)
                            {
                                gameInfo.MinMission = 2;
                                updateMinMission(gameInfo.MinMission);
                            }
                        }
                        break;
                    }
                case 2:
                    {
                        if (checkTeamWin())
                        {
                            if (gameInfo.MinMission == 2)
                            {
                                gameInfo.MinMission = 3;
                                updateMinMission(gameInfo.MinMission);
                            }
                        }
                        break;
                    }
                case 3:
                    {
                        if (checkPlayerWin())
                        {
                            if (gameInfo.MinMission == 3)
                            {
                                gameInfo.MinMission = 4;
                                updateMinMission(gameInfo.MinMission);
                            }
                        }
                        break;
                    }
                case 4:
                    {
                        if (checkKillsWin(9))
                        {
                            if (gameInfo.MinMission == 4)
                            {
                                gameInfo.MinMission = 5;
                                updateMinMission(gameInfo.MinMission);
                            }
                        }
                        break;
                    }
                case 5:
                    {
                        if (checkPlayerWin())
                        {
                            if (gameInfo.MinMission == 5)
                            {
                                gameInfo.MinMission = 6;
                                updateMinMission(gameInfo.MinMission);
                            }
                        }
                        break;
                    }
                case 6:
                    {
                        if (checkKillsWin(6))
                        {
                            if (gameInfo.MinMission == 6)
                            {
                                gameInfo.MinMission = 7;
                                updateMinMission(gameInfo.MinMission);
                            }
                        }
                        break;
                    }
                case 7:
                    {
                        if (checkPlayerWin())
                        {
                            if (gameInfo.MinMission == 7)
                            {
                                gameInfo.MinMission = 8;
                                updateMinMission(gameInfo.MinMission);
                            }
                        }
                        break;
                    }
                case 8:
                    {
                        if (checkPlayerWin())
                        {
                            if (gameInfo.MinMission == 8)
                            {
                                gameInfo.MinMission = 9;
                                updateMinMission(gameInfo.MinMission);
                            }
                        }
                        break;
                    }
                case 9:
                    {
                        if (checkPlayerWin())
                        {
                            if (gameInfo.MinMission == 9)
                            {
                                gameInfo.MinMission = 10;
                                updateMinMission(gameInfo.MinMission);
                            }
                        }
                        break;
                    }
                case 10:
                    {
                        if (checkStarWin(5))
                        {
                            if (gameInfo.MinMission == 10)
                            {
                                gameInfo.MinMission = 11;
                                updateMinMission(gameInfo.MinMission);
                            }
                        }
                        break;
                    }
                case 11:
                    {
                        if (checkTeamWin())
                        {
                            if (gameInfo.MinMission == 11)
                            {
                                gameInfo.MinMission = 12;
                                updateMinMission(gameInfo.MinMission);
                            }
                        }
                        break;
                    }
                case 12:
                    {
                        if (checkPlayerWin())
                        {
                            if (gameInfo.MinMission == 12)
                            {
                                gameInfo.MinMission = 13;
                                updateMinMission(gameInfo.MinMission);
                            }
                        }
                        break;
                    }
                case 13:
                    {
                        ArrayList characters = gameInfo.getCharacters();
                        if (characters.Count == 1)
                        {
                            Object obj = (Object)characters[0];
                            if (obj.Name == "player1")
                            {
                                status = "win";
                                textCurrectMenu = textPlayer1Win;
                            }
                            else
                            {
                                status = "win";
                                textCurrectMenu = textPlayer2Win;
                            }
                            /*
                            if (obj.Team == "green")
                            {
                                status = "win";
                                textCurrectMenu = textPlayerWin;
                                return true;
                            }
                            else
                            {
                                status = "gameOver";
                                textCurrectMenu = textGameOver;
                            }*/
                        }
                        break;
                    }
            }
        }

        /// <summary>
        /// Allows the game to run logic such as updating the world,
        /// checking for collisions, gathering input, and playing audio.
        /// </summary>
        /// <param name="gameTime">Provides a snapshot of timing values.</param>
        protected override void Update(GameTime gameTime)
        {
            timeLastKey += gameTime.ElapsedGameTime.Milliseconds;
            if (timeLastKey > 10)
            {
                timeLastKey = 0;
                KeyboardState keyState = Keyboard.GetState();
              
                //Player player = (Player)gameInfo.g

                switch (status)
                {
                    case "game":
                        {
                            if (initialCount <= 0)
                            {
                                Player player = null;
                                Keys[] keys = keyState.GetPressedKeys();

                                for (int i = 0; i < keys.Length; i++)
                                {
                                    String key = keys[i].ToString();
                                    switch (key)
                                    {
                                        case "Left":
                                            {
                                                player = (Player)gameInfo.getPlayer("player1");
                                                if (player == null)
                                                    player = (Player)gameInfo.getPlayer("player");
                                                if (player != null)
                                                    gameInfo.moveLeft(player);
                                                break;
                                            }
                                        case "Right":
                                            {
                                                player = (Player)gameInfo.getPlayer("player1");
                                                if (player == null)
                                                    player = (Player)gameInfo.getPlayer("player");
                                                if (player != null)
                                                    gameInfo.moveRight(player);
                                                break;
                                            }
                                        case "Up":
                                            {
                                                player = (Player)gameInfo.getPlayer("player1");
                                                if (player == null)
                                                    player = (Player)gameInfo.getPlayer("player");
                                                if (player != null)
                                                    gameInfo.moveUp(player);
                                                break;
                                            }
                                        case "Down":
                                            {
                                                player = (Player)gameInfo.getPlayer("player1");
                                                if (player == null)
                                                    player = (Player)gameInfo.getPlayer("player");
                                                if (player != null)
                                                    gameInfo.moveDown(player);
                                                break;
                                            }
                                        case "W":
                                            {
                                                player = (Player)gameInfo.getPlayer("player2");
                                                if (player != null)
                                                    gameInfo.moveUp(player);
                                                break;
                                            }
                                        case "A":
                                            {
                                                player = (Player)gameInfo.getPlayer("player2");
                                                if (player != null)
                                                    gameInfo.moveLeft(player);
                                                break;
                                            }
                                        case "D":
                                            {
                                                player = (Player)gameInfo.getPlayer("player2");
                                                if (player != null)
                                                    gameInfo.moveRight(player);
                                                break;
                                            }
                                        case "S":
                                            {
                                                player = (Player)gameInfo.getPlayer("player2");
                                                if (player != null)
                                                    gameInfo.moveDown(player);
                                                break;
                                            }
                                        default:
                                            {
                                                break;
                                            }
                                    }
                                }

                                if (keyState.IsKeyDown(Keys.B))
                                {
                                    player = (Player)gameInfo.getPlayer("player1");
                                    if (player == null)
                                        player = (Player)gameInfo.getPlayer("player");
                                    if (player != null)
                                        gameInfo.attackBomb(player);
                                }
                                if (keyState.IsKeyDown(Keys.V))
                                {
                                    player = (Player)gameInfo.getPlayer("player1");
                                    if (player == null)
                                        player = (Player)gameInfo.getPlayer("player");
                                    if (player != null)
                                        gameInfo.attackGun(player);
                                }
                                if (keyState.IsKeyDown(Keys.O))
                                {
                                    player = (Player)gameInfo.getPlayer("player2");
                                    if (player != null)
                                        gameInfo.attackBomb(player);
                                }
                                if (keyState.IsKeyDown(Keys.I))
                                {
                                    player = (Player)gameInfo.getPlayer("player2");
                                    if (player != null)
                                        gameInfo.attackGun(player);
                                }


                            }
                            if (keyState.IsKeyDown(Keys.F1) && lastState.IsKeyUp(Keys.F1))
                            {
                                enableMusic = !enableMusic;
                            }
                            if (keyState.IsKeyDown(Keys.F2) && lastState.IsKeyUp(Keys.F2))
                            {
                                modeDebug = !modeDebug;
                            }
                            if (keyState.IsKeyDown(Keys.R) && lastState.IsKeyUp(Keys.R))
                            {
                                initialCount = 3;
                                loadLevel(gameInfo.Level);
                            }
                            if (keyState.IsKeyDown(Keys.Escape) && lastState.IsKeyUp(Keys.Escape))
                            {
                                if(gameInfo.Level == 13)
                                    status = "menu";
                                else
                                    status = "selectMision";
                            }                     
                            break;
                        }
                    case "gameOver":
                        {
                            if (keyState.IsKeyDown(Keys.Enter))
                            {
                                status = "selectMision";
                            }
                            break;
                        }
                    case "howtoplay":
                        {
                            textCurrectMenu = textHowtoplay;
                            MouseState mouseState = Mouse.GetState();
                            if (mouseState.X > 0 && mouseState.X < 120 && mouseState.Y > 0 && mouseState.Y < 86)
                            {
                                textCurrectMenu = textHowtoplayBack;
                                if (mouseState.LeftButton == ButtonState.Pressed)
                                    status = "menu";
                            }
                            if (keyState.IsKeyDown(Keys.Escape) && lastState.IsKeyUp(Keys.Escape))
                                status = "menu";
                            break;
                        }
                    case "selectMision":
                        {
                            textCurrectMenu = textMenuSelectMission;
                            MouseState mouseState = Mouse.GetState();
                            if (mouseState.X > 0 && mouseState.X < 120 && mouseState.Y > 0 && mouseState.Y < 86)
                            {
                                textCurrectMenu = textMenuSelectMissionBack;
                                if (mouseState.LeftButton == ButtonState.Pressed)
                                    status = "menu";
                            }
                            if (keyState.IsKeyDown(Keys.Escape) && lastState.IsKeyUp(Keys.Escape))
                                status = "menu";
                            break;
                        }
                    case "menu":
                        {
                            Boolean selected = true;
                            MouseState mouseState = Mouse.GetState();
                           //if (mouseState.LeftButton == ButtonState.Pressed)
                            //{
                                int width = 300;
                                int height = 65;
                                int x = 160;
                                int y = 195;

                                int posX = mouseState.X;
                                int posY = mouseState.Y;
                                if (posX > x && posX < x+width && posY > y && posY < y+height)
                                {
                                    textCurrectMenu = textMenuSoloPlay;
                                    // Mission mode
                                    if (mouseState.LeftButton == ButtonState.Pressed)
                                    {
                                        //textCurrectMenu = textMenuSelectMission;
                                        status = "selectMision";
                                        //status = "game";
                                    }
                                    
                                   // status = "popupLevel";
                                }
                                else
                                {
                                    x = 578;
                                    y = 195;
                                    if (posX > x && posX < x + width && posY > y && posY < y + height)
                                    {
                                        // start game
                                        if (mouseState.LeftButton == ButtonState.Pressed)
                                        {
                                            status = "game";
                                            initialCount = 3;
                                            gameInfo.Level = 13;
                                            loadMission(13);
                                        }
                                        textCurrectMenu = textMenuBattlePlay;
                                        // status = "popupLevel";
                                    }
                                    else
                                    {
                                        x = 386;
                                        y = 380;
                                        if (posX > x && posX < x + width && posY > y && posY < y + height)
                                        {
                                            textCurrectMenu = textMenuHowToPlay;
                                            // start game
                                            if (mouseState.LeftButton == ButtonState.Pressed)
                                            {
                                                //textCurrectMenu = textHowtoplay;
                                                //System.Console.WriteLine("bien");
                                                status = "howtoplay";
                                            }
                                            
                                            // status = "popupLevel";
                                        }
                                        else
                                        {
                                            x = 386;
                                            y = 465;
                                            if (posX > x && posX < x + width && posY > y && posY < y + height)
                                            {
                                                if (mouseState.LeftButton == ButtonState.Pressed)
                                                    Exit();
                                                textCurrectMenu = textMenuExit;
                                            }
                                            else
                                            {
                                                selected = false;
                                                textCurrectMenu = textMenu;
                                            }
                                        }
                                    }
                                }

                                if (selected == true && previousSelected == false)
                                {
                                    //if (enableMusic)
                                      //  selectedOption.Play();
                                }
                                previousSelected = selected;
                           // }
                            break;
                        }
                    case "win":
                        {
                            if (keyState.IsKeyDown(Keys.Enter) && lastState.IsKeyUp(Keys.Enter))
                            {
                                if (gameInfo.Level == 13)
                                {
                                    initialCount = 3;
                                    status = "game";
                                    loadLevel(gameInfo.Level);
                                }
                                else
                                {
                                    status = "selectMision";
                                }
                                /*
                                gameInfo.Level++;
                                initialCount = 3;
                                status = "game";
                                loadLevel(gameInfo.Level);*/
                            }
                            if (keyState.IsKeyDown(Keys.Space) && lastState.IsKeyUp(Keys.Space))
                            {
                                /*
                                gameInfo.Level++;
                                initialCount = 3;
                                status = "game";
                                loadLevel(gameInfo.Level);
                                 */
                            }
                            
                            break;
                        }
                }
                lastState = keyState;
            }
          
            //for(int i = 0; i < keys.Length; i++)
            //    System.Console.WriteLine(i + ":" + keys[i]);

            base.Update(gameTime);
        }


        public void drawGame()
        {
            spriteBatch.Begin();

            spriteBatch.Draw(textBackground, new Rectangle(0, 0, textBackground.Width, textBackground.Height), Color.White);

            if (modeDebug)
            {
                for (int i = 0; i < world.Rows; i++)
                {
                    for (int j = 0; j < world.Columns; j++)
                        spriteBatch.Draw(textCell, new Rectangle(j * map.TileWidth, i * map.TileWidth, map.TileWidth, map.TileWidth), Color.White);
                }
            }
            map.Draw(spriteBatch);

            spriteBatch.End();

            

            if (modeDebug)
            {
                //gameInfo.drawLivesPlayers();
                gameInfo.drawCellVisionEnemies();
                //gameInfo.drawColisions();
            }

            gameInfo.draw();
            gameInfo.drawPlayerAmmo();

        }

        /// <summary>
        /// This is called when the game should draw itself.
        /// </summary>
        /// <param name="gameTime">Provides a snapshot of timing values.</param>
        protected override void Draw(GameTime gameTime)
        {
            GraphicsDevice.Clear(Color.Gray);

            switch (status)
            {
                case "game":
                    {
                        


                        
                        //gameInfo.drawExplosions();
                        timeLastDraw += gameTime.ElapsedGameTime.Milliseconds;
                        if (timeLastDraw > 10)
                        {
                            timeLastDraw = 0;
                            drawGame();
                            
                        }

                        if (initialCount <= 0)
                        {
                            timeLastItem += gameTime.ElapsedGameTime.Milliseconds;
                            if (timeLastItem > 8000)
                            {
                                timeLastItem = 0;
                                gameInfo.createRandomItem();
                                //System.Console.ReadKey();
                            }

                            timeLastUpdate += gameTime.ElapsedGameTime.Milliseconds;
                            if (timeLastUpdate > 18)
                            {
                                timeLastUpdate = 0;
                                //gameInfo.Player.update();

                                aiInterface.update();

                                gameInfo.updateGLX();

                            }
                        }

                        checkFinish();

                        if (initialCount >= 0)
                        {
                            timeInitialCount += gameTime.ElapsedGameTime.Milliseconds;
                            if (timeInitialCount > 1000)
                            {
                                timeInitialCount = 0;
                                System.Console.WriteLine(initialCount);
                                initialCount--;
                            }
                            spriteBatch.Begin();
                            switch (initialCount)
                            {
                                case 3:
                                    {
                                        spriteBatch.Draw(text3, new Rectangle(0, 0, text3.Width, text3.Height), Color.White);
                                        break;
                                    }
                                case 2:
                                    {
                                        spriteBatch.Draw(text2, new Rectangle(0, 0, text2.Width, text2.Height), Color.White);
                                        break;
                                    }
                                case 1:
                                    {
                                        spriteBatch.Draw(text1, new Rectangle(0, 0, text1.Width, text1.Height), Color.White);
                                        break;
                                    }
                                case 0:
                                    {
                                        spriteBatch.Draw(textGo, new Rectangle(0, 0, textGo.Width, textGo.Height), Color.White);
                                        break;
                                    }
                            }

                            spriteBatch.End();
                        }
                        break;
                    }
                case "gameOver":
                    {

                        drawGame();

                        spriteBatch.Begin();

                        spriteBatch.Draw(textGameOver, new Rectangle(0, 0, textGameOver.Width, textGameOver.Height), Color.White);

                        spriteBatch.End();

                        break;
                    }
                case "win":
                    {
                        drawGame();
                        spriteBatch.Begin();

                        spriteBatch.Draw(textCurrectMenu, new Rectangle(0, 0, textCurrectMenu.Width, textCurrectMenu.Height), Color.White);

                        spriteBatch.End();
                        break;
                    }
                case "menu":
                    {
                        spriteBatch.Begin();

                        spriteBatch.Draw(textCurrectMenu, new Rectangle(0, 0, textCurrectMenu.Width, textCurrectMenu.Height), Color.White);

                        spriteBatch.End();
                        break;
                    }
                case "howtoplay":
                    {
                        spriteBatch.Begin();

                        spriteBatch.Draw(textCurrectMenu, new Rectangle(0, 0, textCurrectMenu.Width, textCurrectMenu.Height), Color.White);

                        spriteBatch.End();
                        break;
                    }
                case "selectMision":
                    {
                        spriteBatch.Begin();

                        spriteBatch.Draw(textCurrectMenu, new Rectangle(0, 0, textCurrectMenu.Width, textCurrectMenu.Height), Color.White);

                        spriteBatch.End();

                        int mission = gameInfo.MinMission;
                        int posX = 830;
                        int posY = 110;
                        for (int i = 1; i <= mission; i++)
                        {

                            spriteBatch.Begin();

                            //spriteBatch.Draw(textMenuEnableMission, new Rectangle(posX, posY, textMenuEnableMission.Width, textMenuEnableMission.Height), Color.White);

                            spriteBatch.End();
                            posY += 43;
                            if (i % 4 == 0)
                                posY += 62;
                        }
                        for (int i = mission + 1; i <= 12; i++)
                        {
                            spriteBatch.Begin();

                            spriteBatch.Draw(textMenuDisableMission, new Rectangle(posX, posY, textMenuDisableMission.Width, textMenuDisableMission.Height), Color.White);

                            spriteBatch.End();
                            posY += 43;
                            if (i % 4 == 0)
                                posY += 62;
                        }


                        MouseState mouseState = Mouse.GetState();
        
                        mission = 12;
                        posX = 830;
                        posY = 110;
                        for (int i = 1; i <= mission; i++)
                        {
                            if (mouseState.X > posX && mouseState.X < posX + 137 && mouseState.Y > posY && mouseState.Y < posY + 40)
                            {
       

                                spriteBatch.Begin();

                                spriteBatch.Draw(textMenuSelectedMission, new Rectangle(posX, posY, textMenuSelectedMission.Width, textMenuSelectedMission.Height), Color.White);

                                spriteBatch.End();

                                // start game
                                // i <= gameInfo.MinMission && 
                                if (i <= gameInfo.MinMission && mouseState.LeftButton == ButtonState.Pressed)
                                {
                                    //System.Console.WriteLine("bien");
                                    status = "game";
                                    initialCount = 3;
                                    gameInfo.Level = i;
                                    loadMission(gameInfo.Level);
                                }
                              
                              

                            }

                            posY += 43;
                            if (i % 4 == 0)
                                posY += 62;
                        }

                        break;
                    }
            }


  
            
            base.Draw(gameTime);
        }
    }
}
